<template>
  <div class="query_input">
    <span style="font-weight: 500">请输入SQL语句
      <a-tooltip>
        <template #title>
          使用 "#{}" 设置占位符动态传值，例如：select * from demo_datasource where id = #{id} and name = '#{name}',字符串类型字段请手动添加''
        </template>
        <a-icon type="question-circle" style="margin-left: 5px;" />
      </a-tooltip>
    </span>
    <a-textarea v-model="sql" style="margin-top: 10px; height: 200px;" :auto-size="false" @change="onTextChangeSql" />
    <a-button type="primary" @click="checkSQL" :loading="loadBtn" icon="search" style="margin-top: 10px;">
      SQL校验
    </a-button>
    <a-modal
      v-model="visible"
      :rules="filter_form.rules"
      title="SQL校验"
      @ok="submitConditionValue"
      :maskClosable="false"
      @cancel="closeConditionModel"
      cancelText="取消"
      okText="校验"
      :loading="loadBtn"
    >
      <a-form-model
        ref="filterForm"
        :model="filter_form"
        :label-col="{ span: 4 }"
        :wrapper-col="{ span: 20 }"
      >
        <a-form-model-item v-for="(item,i) in filter_form.items" :label="item.name" :prop="item.name" :key="i">
          <a-input v-model="item.value" placeholder="请输入具体条件值" />
        </a-form-model-item>
      </a-form-model>
    </a-modal>

  </div>
</template>

<script>
import bus from "@/views/components/bus";

const filter_reg = /#{(.+?)}/g;
const old_filter_reg = /\${(.+?)}/g;

import { mapActions, mapMutations } from 'vuex';
import store from '@/store';

  export default {
    props:['queryForm'],
    data() {
      return {
        visible:false,
        filter_form: {
          items:[],
          rules:{}
        },
        filterSet: {},
        sql: localStorage.getItem('sql_query') || '',
        loadBtn: false,
        sqlPlace: [],
        filter_checked:false,
      }
    },
    watch: {
      sql (val) {
        this.queryForm.config.sql = val
        if (!val) {
          this.sqlPlace = []
        }
      },
      visible (val){
        if (!val){
          this.filter_form = {
            items:[],
            rules:{}
          }
        }
      }
    },
    mounted () {
      bus.$off('filterCheck')
      bus.$on('filterCheck',callback => {
        callback(this.filter_checked)
      })
      if (this.queryForm.id) {
        this.sql = this.queryForm.config.sql
        this.filter_checked = true
      }
    },
    methods: {
      ...mapActions('sql_query', ['searchSQLQuery']),
      ...mapMutations('sql_query', ['SET_FILTER_COLUMNS']),
      onTextChangeSql () {
        localStorage.setItem('sql_query', this.sql)
        this.SET_FILTER_COLUMNS([])
        this.filter_checked=false
        this.queryForm.filter = []
      },
      checkSQL (){
        if(!this.sql){
          this.$message.error('请输入sql再进行校验')
          return
        }
        let sql_format = this.sql.replace(/\s/g, '');
        if (sql_format.match(old_filter_reg)){
          this.$message.error('当前sql包含旧版占位符"${}",请替换为"#{}"后重试')
          this.filter_checked=false
          return
        }
        let result = sql_format.match(filter_reg);
        this.filterSet = new Set()
        result && result.length > 0 && result.forEach(item => {
          let key = item.substr(2, item.length -3)
          this.filterSet.add(key)
        });
        const filterColumns = []
        this.filterSet.forEach(item => {
          this.filter_form.items.push({
            name: item,
            value: ""
          })
          this.filter_form.rules[item] = [
            {
              required: true,
              trigger: 'blur',
              message: '请输入具体条件值'
            }
          ]
          filterColumns.push({
            name: item,
            displayName: item,
            dataType: 'string',
            type: 'input',
            optionType: '无',
          })
        })
        this.visible = true
        this.SET_FILTER_COLUMNS(filterColumns)
      },
      query (sql) {
        this.loadBtn  = true
        return new Promise((resolve, reject) => {
          this.searchSQLQuery({sql: sql, id: this.queryForm.datasourceId})
            .then(res => {
              resolve(res)
            })
            .catch(err => {
              reject(err)
            })
            .finally(_=>{
              this.loadBtn  = false
            })
        })
      },
      submitConditionValue(){
        this.$refs.filterForm.validate(valid => {
          if (!valid){
            return
          }
          const items = this.filter_form.items
          let sql = String(this.sql).trim()
          if (sql.indexOf('limit') < 0){
            if (sql.endsWith(';')){
              sql = sql.substring(0,sql.length - 1) + '  limit 100;'
            }else {
              sql = sql + '  limit 100'
            }
          }
          for (let i in items){
            const regx = new RegExp("#{" + items[i].name + "}", 'g');
            sql = sql.replace(regx,items[i].value)
          }
          this.query(sql).then( res => {
            this.loadBtn  = true
            if (res.data.result && res.data.result.length > 0){
              this.filter_checked = true
              const output = []
              const columns = res.data.columns
              columns.map(item => {
                output.push({
                  name : item,
                  displayName: item
                })
              })
              this.queryForm.output = output
              this.$message.success('SQL校验成功')
              this.visible = false
            }else {
              this.$message.error('未获取到数据，请检查表是否为空或查询条件设置有误')
            }

          }).catch(err => {
            console.error(err)
            this.$message.error('SQL校验失败，原因：'+ err.msg + '！')
          }).finally(_=>{
            this.loadBtn  = false
          })
        })
      },
      closeConditionModel(){
        this.visible = false
      }
    }
  }
</script>

<style scoped>
.query_input{
  padding: 15px;
  height: auto;
}
</style>
